package com.siyoumi.sh.modules.gzhc365;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.siyoumi.sh.modules.common.IHandle;
import com.siyoumi.sh.modules.common.send_msg.TlSendMsg;
import com.siyoumi.sh.modules.gzhc365.entity.GzhcApiToken;
import com.siyoumi.sh.modules.gzhc365.entity.GzhcDoctor;
import com.siyoumi.sh.modules.gzhc365.entity.GzhcDoctorWorkToday;
import com.siyoumi.util.XApp;
import com.siyoumi.util.XDate;
import com.siyoumi.util.XReturn;
import com.siyoumi.util.XStr;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

//抢号 省中医
@Slf4j
public class GzhcHandle34
        extends GzhcHandleBase
        implements IHandle {

    @SneakyThrows
    @Override
    public void run() {
        TlSendMsg.remove();

        List<GzhcApiToken> tokenArr = getArrToken();
        if (tokenArr.size() <= 0) {
            log.error("未配置GZHC_TOKEN");
            return;
        }
        log.info("BEGIN: {}", XDate.toDateTimeString());

        GzhcDoctor doctorTest = new GzhcDoctor();
        {
            doctorTest.setHisId("34"); //医院（省中医）
            //大德路 443
            //大学城 447
            doctorTest.setSubHisId("443");
            doctorTest.setPlatformSource("3");
            doctorTest.setSubSource("11");
            doctorTest.setId("1603"); //徐珉
            //doctorTest.setTest(true);
        }

        LocalDateTime startTime = XDate.parse("2023-11-03 20:59:10");

        GzhcApiToken apiToken = getArrToken().get(0);

        while (true) {
            Duration between = XDate.between(XDate.now(), startTime);
            long seconds = between.getSeconds();
            log.info("left seconds: {}", seconds);
            if (seconds <= 0) {
                logAndSet(TlSendMsg.get(), "**准备抢号** \n\n");
                break;
            }

            XApp.sleep(1);
        }

        play(apiToken, doctorTest);

        TlSendMsg.remove();
        log.info("END: {}", XDate.toDateTimeString());
    }

    private void play(GzhcApiToken apiToken, GzhcDoctor doctor) {
        List<GzhcDoctorWorkToday> listDoctorWork;

        while (true) {
            listDoctorWork = getDoctorWork(apiToken, doctor);
            if (listDoctorWork == null) {
                //接口报错
                //sendMsg(TlSendMsg.get().toString());
                break;
            }
            if (listDoctorWork.size() <= 0) {
                logAndSet(TlSendMsg.get(), "医生还没有放号，继续等待\n\n");
            } else {
                //有号跳出
                break;
            }

            //等1秒
            sleepAndLog(1);
        }

        if (listDoctorWork == null) {
            //接口报错
            sendMsg(TlSendMsg.get().toString());
            return;
        }


        for (GzhcDoctorWorkToday doctorWork : listDoctorWork) {
            logAndSet(TlSendMsg.get(), XStr.format("{0}[{4}]-{3}:{1}/{2}\n\n", XDate.toDateString(doctorWork.getDate())
                    , doctorWork.getLeftNum().toString()
                    , doctorWork.getTotalNum().toString()
                    , doctorWork.getExtFields()
                    , doctorWork.getTime()
                    )
            );
        }

        GzhcDoctorWorkToday doctorWorkMax = listDoctorWork.get(0);
        logAndSet(TlSendMsg.get(), "**优先选择最晚的挂号** \n\n");
        logAndSet(TlSendMsg.get(), XStr.format("{0}-{3}:{1}/{2},{4}\n\n", XDate.toDateString(doctorWorkMax.getDate())
                , doctorWorkMax.getLeftNum().toString()
                , doctorWorkMax.getTotalNum().toString()
                , doctorWorkMax.getExtFields()
                , doctorWorkMax.getTimeType().toString()
                )
        );

        qiang(apiToken, doctor, doctorWorkMax);

        sendMsg(TlSendMsg.get().toString());
    }


    //获取医生挂号记录
    private List<GzhcDoctorWorkToday> getDoctorWork(GzhcApiToken apiToken, GzhcDoctor doctor) {
        String url = "https://mix.med.gzhc365.com/api/customize/getOhterDeptRegSourceResult?_route=h34&";

        Map<String, String> postData = new HashMap<>();
        postData.put("hisId", doctor.getHisId());
        postData.put("subHisId", doctor.getSubHisId());
        postData.put("platformId", doctor.getPlatformId());
        postData.put("platformSource", doctor.getPlatformSource());
        postData.put("subSource", doctor.getSubSource());
        postData.put("doctorCode", doctor.getId());
        postData.put("login_access_token", apiToken.getToken());

        XReturn r = forPostForm(url, getHeader(), postData);
        if (r.err()) {
            logAndSet(TlSendMsg.get(), "获取医生挂号记录失败：" + r.getErrMsg() + "\n\n");
            return null;
        }

        LinkedList<GzhcDoctorWorkToday> listData = new LinkedList<>();

        //String key = "大学城医院";
        String key = "大德路总院";

        JSONObject data = (JSONObject) r.get("data");
        JSONObject maps = data.getJSONObject("maps");
        JSONObject targetMap = maps.getJSONObject(key);

        for (Map.Entry<String, Object> entry : targetMap.entrySet()) {
            JSONArray arrDept = (JSONArray) entry.getValue();
            for (Object o : arrDept) {
                JSONObject deptObj = (JSONObject) o;

                //开疹时间段，例：14:00-16:30
                String timeRange = deptObj.getString("timeRange");
                //1400,1630
                String[] timeRangeArr = timeRange.replace(":", "").split("-");
                Integer timeBegin = XStr.toInt(timeRangeArr[0]);
                Integer timeEnd = XStr.toInt(timeRangeArr[1]);

                String workDate = deptObj.getString("workDate");

                GzhcDoctorWorkToday doctorWork = new GzhcDoctorWorkToday();
                doctorWork.setDate(XDate.parse(workDate));
                doctorWork.setTime(timeRange);
                doctorWork.setDeptNo(deptObj.getString("deptId"));
                doctorWork.setExtFields(deptObj.getString("deptName"));
                doctorWork.setRegFee(deptObj.getInteger("sumFee"));
                doctorWork.setTotalNum(deptObj.getInteger("remain"));
                doctorWork.setLeftNum(deptObj.getInteger("remain"));

                if (!doctorWork.getDate().isAfter(XDate.parse("2023-11-01"))) {
                    continue;
                }

                doctorWork.setTimeType(2); //全天
                if (timeBegin > 1200) {
                    doctorWork.setTimeType(1); //下午
                }
                if (timeEnd < 1200) {
                    doctorWork.setTimeType(0); //早上
                }

                if (doctorWork.getLeftNum() <= 0) {
                    //没库存跳过
                    if (!doctor.getTest()) {
                        continue;
                    }
                }

                if (doctorWork.getTimeType() == 1) {
                    listData.addFirst(doctorWork);
                } else if (doctorWork.getTimeType() == 0) {
                    listData.addLast(doctorWork);
                } else {
                    listData.add(doctorWork);
                }

            }
        }

        return listData;
    }
}
